#include "ring_shm.h"

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

namespace ring_shm
{

RingSHM* RingSHM::Create(const std::string& prefix,
    const size_t count, const size_t bytes)
{
    RingSHM* shm = new(std::nothrow) RingSHM(prefix, count);
    if (!shm) {
        goto return_nullptr;
    }
    for (int i = 0; i < count; ++i) {
        auto name = prefix + std::to_string(i);
        int fd = shm_open(name.c_str(), O_RDWR | O_CREAT, 0666);
        if (fd < 0) {
            goto handle_shm_open_error;
        }
        //设置共享内存的文件大小
        int ret = ftruncate(fd, bytes);
        if (ret < 0) {
            goto handle_shm_open_error;
        }
        m_records[fd] = name;
        m_list.push_back(fd);
    }
    return shm;
handle_shm_open_error:
    while (m_list.size() > 0) {
        int fd = m_list.front();
        auto& name = m_records[fd];
        shm_unlink(name.c_str());
        m_list.pop_front();
    }
    delete shm;
return_nullptr:
    return nullptr;
}

RingSHM::~RingSHM()
{
    while (m_list.size() > 0) {
        int fd = m_list.front();
        auto& name = m_records[fd];
        shm_unlink(name.c_str());
        m_list.pop_front();
    }
    delete this;
}


} // namespace ring_shm